package com.yuji.aacar.net.convertfactory;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.yuji.aacar.net.bean.HttpCoreBaseRequest;
import com.yuji.aacar.net.bean.HttpCoreRequestHeader;
import com.yuji.aacar.net.bean.HttpCoreRequestKVBean;
import com.yuji.aacar.net.config.BlueLog;
import com.yuji.aacar.net.config.HttpConfig;
import com.yuji.aacar.net.config.HttpCoreDES;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Iterator;
import java.util.TreeMap;

import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Converter;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Action1;
import rx.functions.Func1;


/**
 * <li>Package:com.ttp.http_core </li>
 * <li>Author: yhj </li>
 * <li>Date: 2017/2/15 </li>
 * <li>Description: Bean 转 Requst 自定义转换器 需要加密</li>
 */
public class JsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
    private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
    protected final Gson gson;
    protected final TypeAdapter<T> adapter;
    protected int code;

    /**
     * 构造器
     */

    public JsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter,int code) {
        this.gson = gson;
        this.adapter = adapter;
        this.code=code;
    }

    /**
     *
     * @param value requstBean
     * @return
     * @throws IOException
     * 将业务Bean转换成对应json 和加密
     */
    @Override
    public RequestBody convert(T value) throws IOException {
        //取出接口号
        int code = 0;
        if (value instanceof HttpCoreBaseRequest) {
            code = ((HttpCoreBaseRequest) value).getRequestCode();
        }

        //TODO 为了保持兼容， 现在请求header和requestBody里面都有请求服务码
        //超类Request
      //  HttpCoreBaseRequestMessage<T> message = new HttpCoreBaseRequestMessage<T>();
        //自定义head
        HttpCoreRequestHeader head = new HttpCoreRequestHeader(this.code!=0?this.code:code);
        //message.setHeader(head);
        //message.setBody(value);

        /**try {
            //1001接口不用加密
           // if (code != SERVICE_CHECK_VERSION&&code !=SERVICE_MAIN_PUSH) {
                //bean转json串
                String json = gson.toJson(value, new TypeToken<T>() {
                }.getType());
                //接收bodyValue的数组
                String[] list = new String[0];
                //没有请求数据不做处理
                if (value != null && !json.equalsIgnoreCase("{}")) {
                    //拼接body的vaule
                    list = catString(json);
                }
                //native md5加密
                String sign = HttpCoreDESUtils.encrypt(list, head.getTimestamp() + "");
                //加密以后放入head
                head.setSign(sign);
                BlueLog.e("md5", sign);
           // }
        } catch (Exception e) {
            e.printStackTrace();
        }
*/
        //将最终bean生成json串
        String bodyJson = gson.toJson(value, new TypeToken<T>() {
        }.getType());
        String headerJson = gson.toJson(head, new TypeToken<HttpCoreRequestHeader>() {
        }.getType());
        BlueLog.e("request", "request body## ：" + code + " " + bodyJson);
        BlueLog.e("request", "request header## ：" + code + " " + headerJson);

        String postBody = null;
        String postHeader = null;
        try {
            postBody = HttpCoreDES.encryptDESwithBase64(bodyJson);
            postHeader = HttpCoreDES.encryptDESwithBase64(headerJson);
        } catch (Exception e) {
            e.printStackTrace();
        }
      /*  try {
            //普通接口des对称加密
            if (code != SERVICE_CHECK_VERSION&&code !=SERVICE_MAIN_PUSH) {
                postBody = HttpCoreDESUtils.encryptDESwithBase64(bodyJson);
                postHeader = HttpCoreDESUtils.encryptDESwithBase64(headerJson);
            } else {
                //1001Base64加密
                postBody = new String(Base64.encode(bodyJson.getBytes(), Base64.NO_WRAP));
                postHeader =new String(Base64.encode(headerJson.getBytes(), Base64.NO_WRAP));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        //表单提交
        FormBody.Builder builder = new FormBody.Builder();
        BlueLog.e("request", "request info ## ：" + postBody);
        BlueLog.e("request", "request header 加密 ## ：" + postHeader);

        BlueLog.e("request", "request info ## ：" + postBody);
        BlueLog.e("request", "request header 加密 ## ：" + postHeader);


        FormBody formBody =value instanceof HttpCoreBaseRequest ?
                builder.addEncoded("info", postBody).addEncoded("Ttp",postHeader).addEncoded(HttpConfig.IS_WEBVIEW,((HttpCoreBaseRequest)value).isWebView()+"")
                .build():
                builder.addEncoded("info", postBody).addEncoded("Ttp",postHeader)
                .build();
        return formBody;
    }

    /**
     *
     * @param json
     * @return
     * @throws Exception
     * 将value按key的升序排序并且丢弃对象和数组
     */
    private String[] catString(String json) throws Exception {
        final TreeMap<String, String> treeMap = new TreeMap();

        JSONObject jsonObject = new JSONObject(json);
        flatmap(jsonObject).subscribe(new Action1<HttpCoreRequestKVBean>() {
            @Override
            public void call(HttpCoreRequestKVBean httpCoreRequestKvBean) {
                treeMap.put(httpCoreRequestKvBean.getName(), httpCoreRequestKvBean.getValue());
            }
        });

        return treeMap.values().toArray(new String[treeMap.values().size()]);
    }

    private Observable<HttpCoreRequestKVBean> flatmap(final JSONObject o) {
        final Iterator<String> iterator = o.keys();
        //遍历json一级对象
        return Observable.create(new Observable.OnSubscribe<String>() {


            @Override
            public void call(Subscriber<? super String> subscriber) {
                while (iterator.hasNext()) {
                    subscriber.onNext(iterator.next());
                }

            }
        }).filter(new Func1<String, Boolean>() {
            //丢弃对象类型和数组类型
            @Override
            public Boolean call(String s) {
                try {
                    if(o.get(s)instanceof JSONObject||o.get(s) instanceof JsonArray){
                        return false;
                    }else {
                        return true;
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                return null;
            }
            //生成键值对放入map
        }).flatMap(new Func1<String, Observable<HttpCoreRequestKVBean>>() {
            @Override
            public Observable<HttpCoreRequestKVBean> call(String key) {
                try {
                    HttpCoreRequestKVBean httpCoreRequestKvBean = new HttpCoreRequestKVBean();
                    httpCoreRequestKvBean.setName(key);
                    httpCoreRequestKvBean.setValue(o.get(key).toString());
                    return Observable.just(httpCoreRequestKvBean);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
    }

    /*private FormBody wrapperMobile(T value,int code){
         HttpCoreBaseRequestMessage<T> message = new HttpCoreBaseRequestMessage<T>();
        //自定义head
        HttpCoreRequestHeader head = new HttpCoreRequestHeader(code);
        message.setHeader(head);
        message.setBody(value);
        String jsonRequest=gson.toJson(message, new TypeToken<HttpCoreBaseRequestMessage<T>>() {
        }.getType());
        BlueLog.e("request", "request body## ：" + code + " " + jsonRequest);
        String base64Request=new String(Base64.encode(jsonRequest.getBytes(), Base64.NO_WRAP));
        return new FormBody.Builder().addEncoded("info", base64Request).build();
    }*/


}